using System;
using System.Collections.Generic;

namespace UFrame
{
    public static class RandomTool
    {
        /// <summary>
        /// 老虎机随机
        /// </summary>
        /// <returns></returns>
        public static int MachineRandom(List<int> list)
        {
            int pro = 0;
            for (int i = 0; i < list.Count; i++)
            {
                pro += list[i];
            }

            int val = UnityEngine.Random.Range(0, pro);

            int lastVal = 0;
            int id = 0;
            for (int i = 0; i < list.Count; i++)
            {
                lastVal += list[i];
                if (val <= lastVal)
                {
                    id = i;
                    break;
                }
            }

            return id;
        }

        public static int[] GetRandomNum(int num, int minValue, int maxValue)

        {
            Random ra = new Random(unchecked((int) DateTime.Now.Ticks));

            int[] arrNum = new int[num];

            int tmp = 0;

            for (int i = 0; i <= num - 1; i++)
            {
                tmp = ra.Next(minValue, maxValue); //随机取数

                arrNum[i] = GetNum(arrNum, tmp, minValue, maxValue, ra); //取出值赋到数组中
            }

            return arrNum;
        }

        public static int GetNum(int[] arrNum, int tmp, int minValue, int maxValue, Random ra)
        {
            int n = 0;

            while (n <= arrNum.Length - 1)

            {
                if (arrNum[n] == tmp) //利用循环判断是否有重复

                {
                    tmp = ra.Next(minValue, maxValue); //重新随机获取。

                    GetNum(arrNum, tmp, minValue, maxValue, ra); //递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
                }

                n++;
            }

            return tmp;
        }


        /// <summary>
        /// 从1开始到max, 随机出一个数组
        /// </summary>
        public static int[] GetRandom(int count, int max)
        {
            //从1开始到20结束
            Random r = new Random();
            int p = r.Next(0, max);

            //定义一个需要数组
            int[] index = new int[count];

            //循环获取
            for (int j = 0; j < count; j++)
            {
                p = Fan(max, index);

                //把获取到的随机数放如数组中方便判断是否有重复的是随机数
                index[j] = p;
            }

            return index;
        }


        /// <summary>
        /// 随机一个不能重复的数字
        /// </summary>
        /// <returns></returns>
        public static void RangeCount(int count, int min, int max, List<int> susList, Action<int> onLottery)
        {
            //判断是否存在死循环
            int dis = max - min;
            if (count > dis)
            {
                throw new Exception("随机的次数 大于 随机范围, 存在死循环. [" + min + ", " + max + "] " + count);
            }

            int chou = 0;

            for (int i = 0; i < count; i++)
            {
                if (susList.Count >= dis)
                {
                    throw new Exception("存在集合造成死循环 存在死循环. [" + min + ", " + max + "] " + susList.Count);
                }

                do
                {
                    chou = UnityEngine.Random.Range(min, max);
                } while (susList.Contains(chou));

                susList.Add(chou);
                if (onLottery != null)
                    onLottery(chou);
            }
        }

        /// <summary>
        /// 随机一个不能重复的数字
        /// </summary>
        /// <returns></returns>
        public static int GetUnique(int min, int max, List<int> uniqueList)
        {
            int dis = max - min;
            if (uniqueList.Count > dis)
            {
                throw new Exception("随机的次数 大于 随机范围, 存在死循环. [" + min + ", " + max + "] " + uniqueList.Count);
            }

            if (uniqueList.Count >= dis)
            {
                throw new Exception("存在集合造成死循环 存在死循环. [" + min + ", " + max + "] " + uniqueList.Count);
            }


            int p = 0; //获取到随机数
            bool has = false;

            do
            {
                has = false;
                p = UnityEngine.Random.Range(min, max);
                for (int i = 0; i < uniqueList.Count; i++)
                {
                    if (p == uniqueList[i])
                    {
                        has = true;
                        break;
                    }
                }
            } while (has);

            uniqueList.Add(p);
            return p;
        }

        /// <summary>
        /// 随机一个不能重复的数字
        /// </summary>
        public static int Fan(int id, int[] index)
        {
            Random r = new Random();

            //获取到随机数
            int p = r.Next(1, id);

            //判断是否获取到相同的随机数
            for (int q = 0; q < index.Length; q++)
            {
                if (p == index[q])
                {
                    //如果获取的数重复重新获取
                    return Fan(id, index);
                }
            }

            return p;
        }

        /// <summary>
        /// 随机排序List
        /// </summary>
        public static List<T> RandomSortList<T>(List<T> ListT)
        {
            Random random = new Random();
            List<T> newList = new List<T>();
            foreach (T item in ListT)
            {
                newList.Insert(random.Next(newList.Count + 1), item);
            }

            return newList;
        }


        /// <summary>
        /// x分之一的机会, 命中true , 否则是 false
        /// </summary>
        /// <param name="ratio"></param>
        /// <returns></returns>
        public static bool RangeHit(int ratio)
        {
            Random random = new Random();
            if (ratio == 0)
            {
                return false;
            }

            if (ratio == 1)
            {
                return true;
            }

            int result = random.Next(1, ratio);
            return result == ratio / 2;
        }

        /// <summary>
        /// 累计值相加会最后一个值会超出 总时间Time Bug
        /// </summary>
        /// <param name="time">总时间</param>
        /// <param name="num">段数</param>
        public static void SegmentCollect(float time, float num, List<float> segmentInterval)
        {
            float ciTime = time / num; //每次的时间
            float minTime = 0.2f;
            float maxTime = 0.8f;
            float minInterval = ciTime - minTime; //最短敲击时间
            float maxInterval = ciTime + maxTime; //最大敲击时间

            float temp = 0f;
            float testAllTime = 0;
            //StringBuilder sbTime = new StringBuilder();
            for (int i = 0; i < num; i++)
            {
                float val = 0;

                if (i == num - 1) //最后一次循环
                {
                    val = time - testAllTime;
                }
                else
                {
                    if (temp > 0) //上一次小于平均值,这次就增加最大区间
                        val = UnityEngine.Random.Range(minInterval, maxInterval + temp);
                    else
                        val = UnityEngine.Random.Range(minInterval + temp, maxInterval);

                    float cha = ciTime - val; //超过平均值就是负, 小于平均值就是正
                    temp += cha;
                }

                segmentInterval.Add(val);
                testAllTime += val;

                //sbTime.AppendLine(val.ToString());
            }

            //
            // Debug.Log("随机出的时间 " + testAllTime + "  游戏倒计时时间 " + time);
            // Debug.Log("各个时间值" + sbTime);
        }
    }
}